﻿using eLoan.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace eLoan.Controllers
{
    public class BorrowerController : BaseController
    {
        public ActionResult AddEditBorrower(int? borrowerID, string branchCode)
        {
            try 
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                var db = new DatabaseContext();
                var model = MasterFilesHelper.GetBorrowerAddEditModel(db, borrowerID, branchCode, User.Identity.Name);
                return View("AddEdit", model);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }

        }

        [HttpPost]
        public ActionResult Save(BorrowerAddEditModel model, string command)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                if (ModelState.IsValid)
                {
                    using (var db = new DatabaseContext())
                    {
                        if (command == AdministrationHelper.DBCommand.Add.ToString())
                        {
                            db.Borrowers.Add(model.BorrowerModel.Borrower);
                            db.SaveChanges();

                            return RedirectToAction("Borrowers", "Masterfile", new { branchCode = model.BorrowerModel.Borrower.BranchCode });

                        }
                        else if (command == AdministrationHelper.DBCommand.Edit.ToString())
                        {
                            db.Entry(model.BorrowerModel.Borrower).State = System.Data.EntityState.Modified;
                            db.SaveChanges();

                            if (!model.BorrowerModel.OldAgentID.Equals(model.BorrowerModel.Borrower.AgentID))
                                TransferActiveLoansOfBorrowerToNewAgent(db, model.BorrowerModel.Borrower.ID, model.BorrowerModel.OldAgentID, model.BorrowerModel.Borrower.AgentID);

                            return RedirectToAction("Borrowers", "Masterfile", new { branchCode = model.BorrowerModel.Borrower.BranchCode });
                        }
                        else
                        {
                            // cancelled
                        }
                    }
                }

                return RedirectToAction("Borrowers", "Masterfile");
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        private void TransferActiveLoansOfBorrowerToNewAgent(DatabaseContext db, int borrowerID, int OldAgentID, int newAgentID)
        {
            var activeLoans = db.Loans.Where(w => w.IsActive 
                                                && w.StatusID != (int)AdministrationHelper.LoanStatus.Closed
                                                && w.BorrowerID == borrowerID
                                                && w.AgentID == OldAgentID);

            foreach (var loan in activeLoans)
            {
                loan.AgentID = newAgentID;
                db.Entry(loan).State = System.Data.EntityState.Modified;
            }

            db.SaveChanges();

        }

        public ActionResult BorrowerDetails(int? borrowerID, string branchCode)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                var db = new DatabaseContext();
                var borrowerDetailsModel = MasterFilesHelper.GetBorrowerDetailsModel(db, borrowerID, branchCode, User.Identity.Name);
                return View(borrowerDetailsModel);

            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        [HttpPost]
        public ActionResult SaveBorrowerDetails(BorrowerDetailsModel model)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                var db = new DatabaseContext();

                db = SaveBorrowerIdentifications(db, model.BorrowerIdentifications);
                db = SaveBorrowerCollaterals(db, model.BorrowerCollaterals);
                db = SaveBorrowerCoMakers(db, model.BorrowerCoMakers);
                db = SaveBorrowerReferences(db, model.BorrowerReferences);

                db.SaveChanges();
                
                db.Dispose();

                return RedirectToAction("Borrowers", "Masterfile", new { branchCode = model.BranchCode });

            }
            catch(Exception ex)
            {
                return View("Error", ex);
            }
        }

        private DatabaseContext SaveBorrowerIdentifications(DatabaseContext db, List<BorrowerIdentification> identifications)
        {
            foreach (var id in identifications)
            {
                if (id.ID > 0)
                {
                    if (string.IsNullOrEmpty(id.IDType) && string.IsNullOrEmpty(id.IDNo))
                        db.Entry(id).State = System.Data.EntityState.Deleted;
                    else
                        db.Entry(id).State = System.Data.EntityState.Modified;
                }
                else
                {
                    if (!string.IsNullOrEmpty(id.IDType) && !string.IsNullOrEmpty(id.IDNo))
                        db.BorrowerIdentifications.Add(id);
                }
            }

            return db;
        }

        private DatabaseContext SaveBorrowerCollaterals(DatabaseContext db, List<BorrowerCollateral> collaterals)
        {
            foreach (var collateral in collaterals)
            {
                if (collateral.ID > 0)
                    if (string.IsNullOrEmpty(collateral.MakeOrType))
                        db.Entry(collateral).State = System.Data.EntityState.Deleted;
                    else
                        db.Entry(collateral).State = System.Data.EntityState.Modified;
                else
                {
                    if (!string.IsNullOrEmpty(collateral.MakeOrType))
                        db.BorrowerCollaterals.Add(collateral);
                }
            }

            return db;
        }

        private DatabaseContext SaveBorrowerCoMakers(DatabaseContext db, List<BorrowerCoMaker> coMakers)
        {
            foreach (var coMaker in coMakers)
            {
                if (coMaker.ID > 0)
                    if (string.IsNullOrEmpty(coMaker.CoMakerName) && string.IsNullOrEmpty(coMaker.Address) && string.IsNullOrEmpty(coMaker.ContactNumbers))
                        db.Entry(coMaker).State = System.Data.EntityState.Deleted;
                    else
                        db.Entry(coMaker).State = System.Data.EntityState.Modified;
                else
                {
                    if (!string.IsNullOrEmpty(coMaker.CoMakerName)
                        && !string.IsNullOrEmpty(coMaker.Address)
                        && !string.IsNullOrEmpty(coMaker.ContactNumbers))
                            db.BorrowerCoMakers.Add(coMaker);
                }

                
            }

            return db;
        }

        private DatabaseContext SaveBorrowerReferences(DatabaseContext db, List<BorrowerReference> references)
        {
            foreach (var reference in references)
            {
                if (reference.ID > 0)
                    if (string.IsNullOrEmpty(reference.Name) && string.IsNullOrEmpty(reference.Relationship) && string.IsNullOrEmpty(reference.ContactNumbers))
                        db.Entry(reference).State = System.Data.EntityState.Deleted;
                    else
                        db.Entry(reference).State = System.Data.EntityState.Modified;
                else
                {
                    if (!string.IsNullOrEmpty(reference.Name)
                        && !string.IsNullOrEmpty(reference.Relationship)
                        && !string.IsNullOrEmpty(reference.ContactNumbers))
                            db.BorrowerReferences.Add(reference);
                }
            }

            return db;
        }

        public ActionResult BorrowerSavings(int? borrowerID)
        {
            try 
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);
                
                var db = new DatabaseContext();
                var model = MasterFilesHelper.GetBorrowerSavingsModel(db, borrowerID);

                return View(model);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        [HttpPost]
        public ActionResult SaveBorrowerSavings(BorrowerSavingsModel model)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                var db = new DatabaseContext();

                var savings = new BorrowerSavings();
                savings.BorrowerID = model.BorrowerID;
                savings.Remarks = model.Remarks;
                savings.Amount = model.Amount;
                savings.DateCreated = DateTime.Now;
                savings.CreatedBy = User.Identity.Name;

                db.BorrowerSavings.Add(savings);
                db.SaveChanges();

                return RedirectToAction("BorrowerSavings", "Borrower", new { borrowerID = model.BorrowerID });

            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult DeleteBorrowerSavings(int? id)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                var db = new DatabaseContext();

                var savings = db.BorrowerSavings.Where(w => w.ID == id).SingleOrDefault<BorrowerSavings>();

                db.BorrowerSavings.Remove(savings);
                db.SaveChanges();

                return RedirectToAction("BorrowerSavings", "Borrower", new { borrowerID = savings.BorrowerID });

            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }
                
        public ActionResult GetAgents(string branchCode)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                var db = new DatabaseContext();

                var agents = db.Agents.Where(w => w.BranchCode == branchCode);
                var agentList = AdministrationHelper.GetAgentDropDownList(agents);

                return Json(agentList, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult CheckIfNameExists(string borrowerName)
        {
            try
            {
                var db = new DatabaseContext();
                
                bool isExists = false;

                var names = db.Borrowers.Select(s => s.BorrowerName);

                if (names.Contains(borrowerName))
                    isExists = true;

                return Json(isExists, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        public ActionResult BorrowerLoanHistory(int? borrowerID)
        {
            try
            {
                CheckUserPageAccess(AdministrationHelper.UserPageAccess.AddressBook);

                var db = new DatabaseContext();
                var model = MasterFilesHelper.GetBorrowerLoanHistoryModel(db, borrowerID);

                return View(model);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }
    }
}
